package com.lab303.powerproject.service;

import com.lab303.powerproject.entity.HistoryData;
import com.lab303.powerproject.entity.Remain;
import com.lab303.powerproject.entity.StrategyOutput;
import com.lab303.powerproject.repository.HistoryDataRepository;
import com.lab303.powerproject.repository.RemainRepository;
import com.lab303.powerproject.repository.StrategyOutputRepository;
import com.lab303.powerproject.util.ColdStrategy;
import com.lab303.powerproject.util.StrategyGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@PropertySource(value = {"classpath:strategy.properties"},
        ignoreResourceNotFound = false, encoding = "UTF-8", name = "strategy.properties")
public class ColdStrategyService {

    @Autowired
    private PredictDataService pd;

    @Autowired
    private ColdStrategy coldStrategy;

    @Autowired
    private HistoryDataRepository historyDataRepository;
    
    @Autowired
    private StrategyGenerator strategyGenerator;

    @Autowired
    private RemainRepository remainRepository;

    @Autowired
    private StrategyOutputRepository sr;

    @Value("#{'${strategy.electricityPrice}'.split(',')}")
    private float[] electricityPrice;

    @Value("${strategy.coefficient}")
    private float coefficient;

    @Value("${strategy.shuiXuNengCap}")
    private float shuiXuNengCap;

    @Value("${strategy.reBengToDiBan}")
    private float reBengToDiBan;

    @Value("${strategy.shuiXunNengToDiBan}")
    private float shuiXunNengToDiBan;

    @Value("${strategy.fallingTem}")
    private float fallingTem;

    @Value("${strategy.risingTem}")
    private float risingTem;

    @Value("${strategy.comfortTem}")
    private float comfortTem;

    @Value("${strategy.holidayBeginTime}")
    private String holidayBeginTime;

    @Value("${strategy.holidayEndTime}")
    private String holidayEndTime;

    private float temprature;  //温度
    private float humidity;    //湿度

    @Scheduled(cron = "0 40 22 * * ?") //每天22时40分执行策略一次
    private void scheduledStrategy() throws IOException, ParseException {
        Date date = new Date();
        generateStrategy(date);
    }


    public Map strategy() throws IOException, ParseException {
        Date date = new Date();
        String format = new SimpleDateFormat("MM-dd").format(date);
        List<HistoryData> historyDataByDateTime = historyDataRepository.findHistoryDataByDateTime(format);
        if (historyDataByDateTime!=null&&historyDataByDateTime.size()>0){
            Map res = new HashMap();
            for (HistoryData historyData:historyDataByDateTime){
                String data = historyData.getData();
                if (data.indexOf(",")!=-1){
                    String[] strings = data.split(",");
                    res.put(historyData.getAlias(), strings);
                }else if (historyData.getData().indexOf(" ")!=-1) {
                    String data1 = historyData.getData();
                    String[] split = data1.split(",");
                    res.put(historyData.getAlias(),split);
                } else{
                    res.put(historyData.getAlias(), historyData.getData());
                }
            }
            return res;
        }else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE,-1);
            Map res = generateStrategy(calendar.getTime());
            return res;
        }
    }

    private Map generateStrategy(Date date) throws IOException, ParseException {
        Calendar calendar  =Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,1);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        Map map;
        Date date1 = calendar.getTime();
        float[] requirement = pd.getPredictDataByDateAndDeviceId(36);
        float[] electricityData = pd.getPredictElectricityDataByDateAndId(1);
        String remain_time = new SimpleDateFormat("MM-dd").format(date);
        String format = new SimpleDateFormat("yyyy-MM-dd").format(date);
        float[] dayAndId = pd.getPredictElectricityDataByDayAndId(format, 36);
        requirement[23] = dayAndId[23];
        Remain remainObject = remainRepository.findRemainByDateTime(remain_time);
        float remain = 500;
        if (remainObject!=null)
            remain = remainObject.getRemainValue();
        map = strategyGenerator.doGenerateStrategy(shuiXuNengCap, reBengToDiBan, shuiXunNengToDiBan, electricityPrice,
                coefficient, fallingTem, risingTem, comfortTem, holidayBeginTime, holidayEndTime, requirement, remain,date);
        float remain1 = (float)map.get("remain");
        Remain remain2 =new Remain();
        remain2.setDate(date1);
        remain2.setRemainValue(remain1);
        remainRepository.saveAndFlush(remain2);
        map.put("electricityData",electricityData);
        map.put("powerData",requirement);

        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        List<HistoryData> list = new ArrayList<>();
        List<StrategyOutput> strategyOutputList = null;
        while (iterator.hasNext()){
            Map.Entry<String, Object> next = iterator.next();
            HistoryData historyData = new HistoryData();
            historyData.setAlias(next.getKey());
            Object value = next.getValue();
            if (value instanceof float[]){
                float[] floats = (float[]) value;
                int i = 0;
                StringBuffer s = new StringBuffer();
                for (;i<floats.length-1;i++){
                    s.append(floats[i]);
                    s.append(",");
                }
                s.append(floats[i]);
                historyData.setData(s.toString());
            }else if (value instanceof String[]){
                String[] strings = (String[]) value;
                int i = 0;
                StringBuffer s = new StringBuffer();
                for (;i<strings.length-1;i++){
                    s.append(strings[i]);
                    s.append(",");
                }
                s.append(strings[i]);
                historyData.setData(s.toString());
            }else if (value instanceof Float) {
                float v = (float) value;
                historyData.setData(String.valueOf(v));
            }else if (value instanceof ArrayList)
            {
                strategyOutputList = (List<StrategyOutput>) value;

            }else {
                historyData.setData((String) next.getValue());
            }
            historyData.setDate(date1);
            if (!historyData.getAlias().equals("strategyOutputList")) {
                list.add(historyData);
            }

        }
        historyDataRepository.saveAll(list);
        sr.saveAll(strategyOutputList);
        return map;
    }
}
